package com.xxchat.controller;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.xxchat.annotation.GlobalInterceptor;
import com.xxchat.entity.constants.QueryConstants;
import com.xxchat.entity.dto.GroupInfoDTO;
import com.xxchat.entity.dto.TokenUserInfoDTO;
import com.xxchat.entity.enums.*;
import com.xxchat.entity.po.UserContact;
import com.xxchat.entity.query.GroupInfoQuery;
import com.xxchat.entity.po.GroupInfo;
import com.xxchat.entity.query.UserContactQuery;
import com.xxchat.entity.vo.GroupInfoVO;
import com.xxchat.entity.vo.ResponseVO;
import com.xxchat.exception.BusinessException;
import com.xxchat.service.GroupInfoService;
import com.xxchat.service.UserContactService;
import com.xxchat.utils.CopyUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

/**
 * 群组信息表 Controller
 *
 * @author Waicc
 */
@RestController("groupController")
@RequestMapping("/group")
@Validated
public class GroupController extends ABaseController {

    @Resource
    private GroupInfoService groupInfoService;

    @Resource
    private UserContactService userContactService;

    /**
     * 新增/修改 群组信息
     *
     * @param groupId     有值表示修改，没值表示新增
     * @param groupName
     * @param joinType
     * @param avatarFile  封面大图
     * @param avatarCover 封面缩略图
     * @return
     */
    @RequestMapping("/saveGroup")
    @GlobalInterceptor
    public ResponseVO saveGroup(HttpServletRequest request,
                                String groupId,
                                @NotEmpty String groupName,
                                @NotNull Integer joinType,
                                String groupNotice,
                                MultipartFile avatarFile,
                                MultipartFile avatarCover) {
        TokenUserInfoDTO userInfo = getTokenUserInfoDTO(request);

        GroupInfo groupInfo = new GroupInfo();
        groupInfo.setGroupId(groupId);
        groupInfo.setGroupName(groupName);
        groupInfo.setJoinType(joinType);
        groupInfo.setGroupOwnerId(userInfo.getUserId());
        groupInfo.setCreateTime(new Date());
        groupInfo.setGroupNotice(groupNotice);
        // TODO 状态要不要设为参数？
        groupInfo.setStatus(GroupStatusEnum.NORMAL.getStatus());
        groupInfoService.saveGroup(groupInfo, avatarFile, avatarCover);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/listGroups")
    @GlobalInterceptor
    public ResponseVO listGroups(HttpServletRequest request) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);
        GroupInfoQuery groupInfoQuery = new GroupInfoQuery();
        groupInfoQuery.setGroupOwnerId(userInfoDTO.getUserId());
        groupInfoQuery.setOrderBy(QueryConstants.ORDER_BY_CREATE_TIME_DESC);
        List<GroupInfo> list = this.groupInfoService.findListByParam(groupInfoQuery);
        return getSuccessResponseVO(list);
    }

    @RequestMapping("/getGroupInfo")
    @GlobalInterceptor
    public ResponseVO getGroupInfo(HttpServletRequest request, @NotEmpty String groupId) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);
        GroupInfo groupInfo = groupInfoService.getGroupInfo(groupId, userInfoDTO);

        UserContactQuery query = new UserContactQuery();
        query.setContactId(groupId);
        Integer count = this.userContactService.findCountByParam(query);

        GroupInfoVO groupInfoVO = CopyUtils.copy(groupInfo, GroupInfoVO.class);
        groupInfoVO.setMemberCount(count);
        return getSuccessResponseVO(groupInfoVO);
    }

    @RequestMapping("/getGroupInfo4Chat")
    @GlobalInterceptor
    public ResponseVO getGroupInfo4Chat(HttpServletRequest request, @NotEmpty String groupId) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);
        GroupInfoDTO groupInfo = groupInfoService.getGroupInfo4Chat(groupId, userInfoDTO);
        GroupInfoVO groupInfoVO = CopyUtils.copy(groupInfo.getGroupInfo(), GroupInfoVO.class);
        groupInfoVO.setUserContactList(groupInfo.getUserContactList());
        return getSuccessResponseVO(groupInfoVO);
    }

    @RequestMapping("/addOrRemoveGroupMember")
    @GlobalInterceptor
    public ResponseVO addOrRemoveGroupMember(HttpServletRequest request,
                                             @NotEmpty String groupId,
                                             @NotEmpty String memberIds,
                                             @NotNull Integer action) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);
        this.groupInfoService.addOrRemoveGroupMember(userInfoDTO, groupId, memberIds, action);
        return getSuccessResponseVO(null);
    }

    // 离开群组
    @RequestMapping("/leaveGroup")
    @GlobalInterceptor
    public ResponseVO leaveGroup(HttpServletRequest request, @NotEmpty String groupId) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);
        UserContact userContact = this.userContactService.getUserContactByContactIdAndUserId(groupId, userInfoDTO.getUserId());
        if (null == userContact) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        this.groupInfoService.leaveGroup(userInfoDTO.getUserId(), groupId, MessageTypeEnum.LEAVE_GROUP);
        return getSuccessResponseVO(null);
    }

    // 群主解散群组
    @RequestMapping("/disbandGroup")
    @GlobalInterceptor
    public ResponseVO disbandGroup(HttpServletRequest request, @NotEmpty String groupId) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);
        GroupInfo groupInfo = this.groupInfoService.getGroupInfoByGroupId(groupId);
        if (null == groupInfo || !groupInfo.getGroupOwnerId().equals(userInfoDTO.getUserId())) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        this.groupInfoService.disbandGroup(userInfoDTO.getUserId(), groupId);
        return getSuccessResponseVO(null);
    }
}